﻿using System;
using System.Collections.Generic;
using System.Text;
using SharpDX.XAudio2;
using System.IO;
using SharpDX.IO;

namespace OpenGameEngine.Audio
{
    /// <summary>
    /// The XAudio2 engine for OpenGameEngine
    /// </summary>
    public static class AudioEngine
    {
        /// <summary>
        /// Gets if the AudioEngine is running
        /// </summary>
        public static Boolean Running { get; private set; }

        private static MasteringVoice m_MasteringVoice;
        private static MasteringVoice MasteringVoice
        {
            get
            {
                if (m_MasteringVoice == null)
                {
                    m_MasteringVoice = new MasteringVoice(XAudio2);
                    m_MasteringVoice.SetVolume(1, 0);
                }
                return m_MasteringVoice;
            }
        }

        private static XAudio2 _xaudio;
        private static XAudio2 XAudio2
        {
            get
            {
                if (_xaudio == null)
                {
                    _xaudio = new XAudio2(XAudio2Flags.None, ProcessorSpecifier.AnyProcessor);
                    _xaudio.CriticalError += (Object o, SharpDX.XAudio2.ErrorEventArgs e) => 
                    { 
                        throw new AudioException(e.ErrorCode, "Critical AudioEngine Error"); 
                    };

                    MasteringVoice v = MasteringVoice;
                }

                return _xaudio;
            }
        }

        /// <summary>
        /// Starts the XAudio2 engine
        /// </summary>
        public static void StartEngine()
        {
            XAudio2.StartEngine();
            Running = true;
        }

        /// <summary>
        /// Stops the XAudio2 engine
        /// </summary>
        public static void StopEngine()
        {
            XAudio2.StopEngine();
            Running = false;
        }

        /// <summary>
        /// Creates a new instance of the <see cref="AudioPlayer"/>
        /// </summary>
        /// <param name="file">The wav audio file</param>
        /// <returns></returns>
        public static AudioPlayer CreatePlayer(String file)
        {
            if (!File.Exists(file))
                throw new FileNotFoundException("The audio file is missing", file);

            using (Stream audioStream = File.Open(file, FileMode.Open, FileAccess.Read))
                return CreatePlayer(audioStream);
        }

        /// <summary>
        /// Creates a new instance of the <see cref="AudioPlayer"/>
        /// </summary>
        /// <param name="audioStream">A stream containing the wav file</param>
        /// <returns></returns>
        public static AudioPlayer CreatePlayer(Stream audioStream)
        {
            if (audioStream == null)
                throw new ArgumentNullException("audioStream");

            return new AudioPlayer(XAudio2, audioStream);
        }
    }
}
